#include "CMsgTrayPos.h"

#include <process.h>
#include <QDebug>

#include "CMsgTrayPos.h"

CTrayPos::CTrayPos()
{
    UINT    uThreadId;

    m_bTrackMouse = FALSE;
    m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    m_hThread = (HANDLE) _beginthreadex(NULL, 0, CTrayPos::TrackMousePt, this, 0, &uThreadId);
    InitializeCriticalSection(&m_cs);
}

CTrayPos::~CTrayPos()
{
    if(m_hThread != NULL)
    {
        qDebug() << "delete";
        SetEvent(m_hExitEvent);
        if(WaitForSingleObject(m_hThread, 1000) == WAIT_TIMEOUT)
        {
            TerminateThread(m_hThread, 0);
        }

        CloseHandle(m_hThread);
        m_hThread = NULL;
    }

    if(m_hExitEvent != NULL)
    {
        CloseHandle(m_hExitEvent);
        m_hExitEvent = NULL;
    }

    DeleteCriticalSection(&m_cs);
    qDebug() << "delete over";
}

UINT CALLBACK CTrayPos::TrackMousePt(PVOID pvClass)
{
    POINT        ptMouse;
    CTrayPos    *pTrayPos = (CTrayPos *) pvClass;

    while(WaitForSingleObject(pTrayPos->m_hExitEvent, 100) == WAIT_TIMEOUT)
    {
        /* 此线程一直处于timeout状态，获取当前坐标，如果
          当移入到label上时，出发move移动，这里会把标志设置为进入，然后判断当在内部时，一直在更新坐标
          所以新获取的也是
*/
        if(pTrayPos->m_bTrackMouse == TRUE)/* 处于跟踪模式才会判断 */
        {
            GetCursorPos(&ptMouse);

            if(ptMouse.x != pTrayPos->m_ptMouse.x || ptMouse.y != pTrayPos->m_ptMouse.y)
            {
                pTrayPos->m_bTrackMouse = FALSE;
                pTrayPos->OnMouseLeave();
            }
        }
    }
    return 0;
}

VOID CTrayPos::OnMouseMove()
{
    EnterCriticalSection(&m_cs);

    GetCursorPos(&m_ptMouse);/* 只要在label上，则一直更新着坐标，当移出时，超时调用，获取坐标不在相等，发出离开信号 */

    if(m_bTrackMouse == FALSE)
    {
        OnMouseHover();
        m_bTrackMouse = TRUE;
    }

    LeaveCriticalSection(&m_cs);
}

BOOL CTrayPos::IsMouseHover()
{
    return m_bTrackMouse;
}

//////////////////////////////////////////////////////////////////////////

CMsgTrayPos::CMsgTrayPos(HWND hwnd, UINT uID, UINT uCallbackMsg)
    : CTrayPos()
{
    SetNotifyIconInfo(hwnd, uID, uCallbackMsg);
}

CMsgTrayPos::~CMsgTrayPos()
{
}

VOID CMsgTrayPos::SetNotifyIconInfo(HWND hwnd, UINT uID, UINT uCallbackMsg)
{
    m_hNotifyWnd = hwnd;//用来发送窗体的id
    m_uID = uID;//用来使用窗体内多id，但是这里只用到了一个
    m_uCallbackMsg = uCallbackMsg;//通知类型
}

VOID CMsgTrayPos::OnMouseHover()
{
    if(m_hNotifyWnd != NULL && IsWindow(m_hNotifyWnd)) {
        PostMessage(m_hNotifyWnd, m_uCallbackMsg, m_uID, WM_MOUSEHOVER);
    }
}

VOID CMsgTrayPos::OnMouseLeave()
{
    if(m_hNotifyWnd != NULL && IsWindow(m_hNotifyWnd))
        PostMessage(m_hNotifyWnd, m_uCallbackMsg, m_uID, WM_MOUSELEAVE);
}
